const geminiService = require('../services/geminiService');
const multer = require('multer');
const config = require('../config/config');

const storage = multer.memoryStorage();
const upload = multer({
  storage: storage,
  limits: {
    fileSize: config.upload.maxFileSize
  },
  fileFilter: (req, file, cb) => {
    if (config.upload.allowedMimeTypes.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new Error(`Invalid file type. Allowed types: ${config.upload.allowedMimeTypes.join(', ')}`));
    }
  }
});

const generateImage = async (req, res, next) => {
  try {
    const { prompt, temperature, topP, topK } = req.body;

    if (!prompt) {
      return res.status(400).json({
        error: 'Bad request',
        message: 'Prompt is required'
      });
    }

    const options = {};
    if (temperature !== undefined || topP !== undefined || topK !== undefined) {
      options.generationConfig = {
        ...config.gemini.generationConfig,
        ...(temperature !== undefined && { temperature }),
        ...(topP !== undefined && { topP }),
        ...(topK !== undefined && { topK })
      };
    }

    const result = await geminiService.generateImage(prompt, options);

    res.json({
      success: true,
      data: {
        images: result.images.map(img => ({
          mimeType: img.mimeType,
          base64: img.data,
          dataUrl: `data:${img.mimeType};base64,${img.data}`
        })),
        text: result.text || null
      }
    });
  } catch (error) {
    next(error);
  }
};

const editImage = async (req, res, next) => {
  try {
    const { prompt, temperature, topP, topK } = req.body;
    const file = req.file;

    if (!file) {
      return res.status(400).json({
        error: 'Bad request',
        message: 'Image file is required'
      });
    }

    if (!prompt) {
      return res.status(400).json({
        error: 'Bad request',
        message: 'Prompt is required'
      });
    }

    const imageData = file.buffer.toString('base64');
    const mimeType = file.mimetype;

    const options = {};
    if (temperature !== undefined || topP !== undefined || topK !== undefined) {
      options.generationConfig = {
        ...config.gemini.generationConfig,
        ...(temperature !== undefined && { temperature }),
        ...(topP !== undefined && { topP }),
        ...(topK !== undefined && { topK })
      };
    }

    const result = await geminiService.editImage(imageData, mimeType, prompt, options);

    res.json({
      success: true,
      data: {
        images: result.images.map(img => ({
          mimeType: img.mimeType,
          base64: img.data,
          dataUrl: `data:${img.mimeType};base64,${img.data}`
        })),
        text: result.text || null
      }
    });
  } catch (error) {
    next(error);
  }
};

const composeImages = async (req, res, next) => {
  try {
    const { prompt, temperature, topP, topK } = req.body;
    const files = req.files;

    if (!files || files.length === 0) {
      return res.status(400).json({
        error: 'Bad request',
        message: 'At least one image file is required'
      });
    }

    if (files.length > 3) {
      return res.status(400).json({
        error: 'Bad request',
        message: 'Maximum 3 images are allowed'
      });
    }

    if (!prompt) {
      return res.status(400).json({
        error: 'Bad request',
        message: 'Prompt is required'
      });
    }

    const images = files.map(file => ({
      data: file.buffer.toString('base64'),
      mimeType: file.mimetype
    }));

    const options = {};
    if (temperature !== undefined || topP !== undefined || topK !== undefined) {
      options.generationConfig = {
        ...config.gemini.generationConfig,
        ...(temperature !== undefined && { temperature }),
        ...(topP !== undefined && { topP }),
        ...(topK !== undefined && { topK })
      };
    }

    const result = await geminiService.composeImages(images, prompt, options);

    res.json({
      success: true,
      data: {
        images: result.images.map(img => ({
          mimeType: img.mimeType,
          base64: img.data,
          dataUrl: `data:${img.mimeType};base64,${img.data}`
        })),
        text: result.text || null
      }
    });
  } catch (error) {
    next(error);
  }
};

const chat = async (req, res, next) => {
  try {
    const { messages, temperature, topP, topK } = req.body;

    if (!messages || !Array.isArray(messages) || messages.length === 0) {
      return res.status(400).json({
        error: 'Bad request',
        message: 'Messages array is required'
      });
    }

    const options = {};
    if (temperature !== undefined || topP !== undefined || topK !== undefined) {
      options.generationConfig = {
        ...config.gemini.generationConfig,
        ...(temperature !== undefined && { temperature }),
        ...(topP !== undefined && { topP }),
        ...(topK !== undefined && { topK })
      };
    }

    const result = await geminiService.chat(messages, options);

    res.json({
      success: true,
      data: {
        images: result.images.map(img => ({
          mimeType: img.mimeType,
          base64: img.data,
          dataUrl: `data:${img.mimeType};base64,${img.data}`
        })),
        text: result.text || null
      }
    });
  } catch (error) {
    next(error);
  }
};

module.exports = {
  generateImage,
  editImage,
  composeImages,
  chat,
  upload
};